home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 9 / FM Towns Free Software Collection 9.iso / t_os / tool / wavfilt / wavfilt.c next >
Encoding:
C/C++ Source or Header  |  1994-11-16  |  11.2 KB  |  466 lines

  1. /*
  2.  *  wavfilt.c --- pre-compresser for MicroSoft WaveForm-File
  3.  *                                   (16bit 44100Hz monoral)
  4.  *                
  5.  *                 (開発履歴)      V2.2   by Togo(とご) [電脳わ~るど]
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <math.h>
  12. #include <limits.h>
  13.  
  14. /* コンパイル条件 */
  15.   // 量子化の手段として16で割る 
  16. #define Q16
  17. //#define NOQ
  18.   // 0のランレングス圧縮等を行う
  19. #define LL 
  20.  
  21. /* 作業ブロック単位 */
  22. #define N  65536
  23. #define M  N/32
  24. #ifdef NOQ
  25.   #define QMAX 1
  26.   #define QMIN 1
  27. #else
  28.   #ifdef Q2
  29.     #define QMIN 2
  30.     #define QMAX 4
  31.   #endif
  32.   #ifdef Q4
  33.     #define QMIN 4
  34.     #define QMAX 8
  35.   #endif
  36.   #ifdef Q8
  37.     #define QMIN 8
  38.     #define QMAX 16
  39.   #endif
  40.   #ifdef Q16
  41.     #define QMIN 16
  42.     #define QMAX 32
  43.   #endif
  44.   #ifdef Q32
  45.     #define QMIN 32
  46.     #define QMAX 64
  47.   #endif
  48.   #ifdef Q64
  49.     #define QMIN 64
  50.     #define QMAX 128
  51.   #endif
  52. #endif
  53.  
  54. static FILE *infile,*outfile;
  55.  
  56. /* 作業用バッファ */
  57. static short buffer[N],
  58.              buf1_1[N/2],buf1_2[N/2],
  59.              buf2_1[N/4],buf2_2[N/4],buf2_3[N/4],buf2_4[N/4],
  60.              buf3_1[N/8],buf3_2[N/8],buf3_3[N/8],buf3_4[N/8],
  61.                 buf3_5[N/8],buf3_6[N/8],
  62.              buf4_1[N/16],buf4_2[N/16],buf4_3[N/16],buf4_4[N/16],
  63.                 buf4_5[N/16],buf4_6[N/16],buf4_7[N/16],buf4_8[N/16],
  64.                 buf4_9[N/16],buf4_10[N/16],
  65.              buf5_1[N/32],buf5_2[N/32],buf5_3[N/32],buf5_4[N/32],
  66.                 buf5_5[N/32],buf5_6[N/32],buf5_7[N/32],buf5_8[N/32],
  67.                 buf5_9[N/32],buf5_10[N/32],buf5_11[N/32],buf5_12[N/32],
  68.                 buf5_13[N/32],buf5_14[N/32],buf5_15[N/32],buf5_16[N/32],
  69.                 buf5_17[N/32],buf5_18[N/32];
  70.  
  71.  
  72. /* 超簡単フィルタ */
  73. void filtering(short *a,short *b,short *c,unsigned long d)
  74. {
  75.   int t,s;
  76.  
  77.   for(t = 0,s = 0; s < d; t+=2,s++){
  78.     b[s] = (a[t+1] + a[t] )/2;
  79.     c[s] = (a[t+1] - a[t] )/2;
  80.   }
  81. }
  82.  
  83. /* 超簡単アンチフィルタ */
  84. void untifilt(short *a,short *b,short *c,unsigned long d)
  85. {
  86.   int t,s;
  87.  
  88.   for(t = 0,s = 0; t < d; t++,s+=2){
  89.     c[s] = a[t] - b[t];
  90.     c[s+1] = a[t] + b[t];
  91.   }
  92. }
  93.  
  94. /* ランレングス圧縮書き込み */
  95. void cswrite(short *buf)
  96. {
  97.   int t,s,square,flag,ctr;
  98.   short tmp;
  99.   int X[M];
  100.  
  101.   t = 0;
  102.   flag = 0;
  103.   square = 0;
  104.  
  105.   for(ctr = 0;ctr < M;ctr++){
  106.     square += (int)buf[ctr]*buf[ctr];
  107.   }
  108.   tmp = (short)(sqrt((double)(square/M)))+1;
  109.   if(tmp < QMIN)tmp = QMIN;
  110.   if(tmp > QMAX)tmp = QMAX;
  111.   fwrite(&tmp,2,1,outfile);
  112.   for(ctr = 0;ctr < M;ctr++){
  113.     buf[ctr] /= tmp;
  114.   }
  115. #ifdef LL
  116.   for(ctr = 0;ctr < M;ctr++){
  117.   /* 2バイト読む */
  118.     tmp = buf[ctr];
  119.   /* 127より上または-127より下のとき 0x80を出力して自身を出力する */
  120.     if(tmp > 127 || tmp < -127){
  121.       if(flag == 1){
  122.         fputc(t,outfile);
  123.         flag = 0;
  124.       }
  125.       fputc(0x80,outfile);
  126.       fwrite(&tmp,2,1,outfile);
  127.     }else{
  128.       if((tmp == 0) && (t < 255)){
  129. //      ランレングスモードの可能性あり
  130.         if(flag == 1){
  131. //        ランレングスモード中
  132.           t++;
  133.         }else{
  134. //        ランレングスモードに入る
  135.           fputc((int)tmp,outfile);
  136.           t = 0;
  137.           flag = 1;
  138.         }
  139.       }else{
  140. //      ランレングスモード脱出の可能性あり
  141.         if(flag == 1){
  142. //        ランレングスモード脱出
  143.           fputc(t,outfile);
  144.           if(t == 255){
  145. //          ランレングスモードに再び入れるように
  146.             ctr--;
  147. //            今の値をキャンセルする
  148.             t = 0;
  149.           }else{
  150.             fputc(tmp,outfile);
  151.           }
  152.           flag = 0;
  153.         }else{
  154. //        元からモードでなかった(^^;とき
  155.           fputc(tmp,outfile);
  156.         }
  157.       }
  158.     }
  159.   }
  160.   if(flag == 1){
  161.     fputc(t,outfile);
  162.   }
  163. #else
  164.   for(ctr = 0;ctr < M;ctr++){
  165.   /* 2バイト読む */
  166.     tmp = buf[ctr];
  167.     fwrite(&tmp,2,1,outfile);
  168.   }
  169. #endif   
  170. }
  171.  
  172. /* 読み込みランレングス伸長 */
  173. void csread(short *buf)
  174. {
  175.   int c,t,ctr,s;
  176.   short tmp;
  177.   int X[M];
  178.   fread(&tmp,2,1,infile);
  179.  
  180. #ifdef LL
  181.   for(ctr = 0;ctr < M;){
  182.     c = fgetc(infile);
  183.     switch(c){
  184.       case 0x80:
  185.         fread(&buf[ctr],2,1,infile);
  186.         buf[ctr] *= tmp;
  187.         ctr++;
  188.         break;
  189.       case 0x00:
  190.         c = fgetc(infile);
  191.         for(t = 0; t < (c & 0xff)+1; t++){
  192.           buf[ctr] = 0;
  193.           ctr++;
  194.         }
  195.         break;
  196.       default:
  197.           buf[ctr] = (short)((signed char)c);
  198.           buf[ctr] *= tmp;
  199.           ctr++;
  200.         break;
  201.     }
  202.   }
  203. #else
  204.   for(ctr = 0;ctr < M;ctr++){
  205.     fread(&buf[ctr],2,1,infile);
  206.     buf[ctr] *= tmp;
  207.   }
  208. #endif
  209.  
  210.  
  211. }
  212.  
  213. void encode(unsigned long size)
  214. {
  215.   unsigned long i,p,q,r,s,t;
  216.   unsigned long m = size / N;
  217.   unsigned long n = size % N;
  218.  
  219.   for(i = 0; i < m; ++i){
  220.     fread((void *)&buffer[0],N*2,1,infile);
  221.       filtering(buffer,buf1_1,buf1_2,N/2);
  222.  
  223.       filtering(buf1_1,buf2_1,buf2_2,N/4);
  224.       filtering(buf1_2,buf2_3,buf2_4,N/4);
  225.  
  226.       filtering(buf2_1,buf3_1,buf3_2,N/8);
  227.       filtering(buf2_2,buf3_3,buf3_4,N/8);
  228.       filtering(buf2_3,buf3_5,buf3_6,N/8);
  229.  
  230.       filtering(buf3_1,buf4_1,buf4_2,N/16);
  231.       filtering(buf3_2,buf4_3,buf4_4,N/16);
  232.       filtering(buf3_3,buf4_5,buf4_6,N/16);
  233.       filtering(buf3_4,buf4_7,buf4_8,N/16);
  234.       filtering(buf3_5,buf4_9,buf4_10,N/16);
  235.  
  236.       filtering(buf4_1,buf5_1,buf5_2,N/32);
  237.       filtering(buf4_2,buf5_3,buf5_4,N/32);
  238.       filtering(buf4_3,buf5_5,buf5_6,N/32);
  239.       filtering(buf4_4,buf5_7,buf5_8,N/32);
  240.       filtering(buf4_5,buf5_9,buf5_10,N/32);
  241.       filtering(buf4_6,buf5_11,buf5_12,N/32);
  242.       filtering(buf4_7,buf5_13,buf5_14,N/32);
  243.       filtering(buf4_8,buf5_15,buf5_16,N/32);
  244.       filtering(buf4_9,buf5_17,buf5_18,N/32);
  245.  
  246.     cswrite(buf5_1);
  247.     cswrite(buf5_2);
  248.     cswrite(buf5_3);
  249.     cswrite(buf5_4);
  250.     cswrite(buf5_5);
  251.     cswrite(buf5_6);
  252.     cswrite(buf5_7);
  253.     cswrite(buf5_8);
  254.     cswrite(buf5_9);
  255.     cswrite(buf5_10);
  256.     cswrite(buf5_11);
  257.     cswrite(buf5_12);
  258.     cswrite(buf5_13);
  259.     cswrite(buf5_14);
  260.     cswrite(buf5_15);
  261.     cswrite(buf5_16);
  262.     cswrite(buf5_17);
  263.     cswrite(buf5_18);
  264.   }
  265.   for(i = 0; i < N; ++i) buffer[i] = 0;
  266.   fread((void *)&buffer[0],n*2,1,infile);
  267.     filtering(buffer,buf1_1,buf1_2,N/2);
  268.  
  269.     filtering(buf1_1,buf2_1,buf2_2,N/4);
  270.     filtering(buf1_2,buf2_3,buf2_4,N/4);
  271.  
  272.     filtering(buf2_1,buf3_1,buf3_2,N/8);
  273.     filtering(buf2_2,buf3_3,buf3_4,N/8);
  274.     filtering(buf2_3,buf3_5,buf3_6,N/8);
  275.  
  276.     filtering(buf3_1,buf4_1,buf4_2,N/16);
  277.     filtering(buf3_2,buf4_3,buf4_4,N/16);
  278.     filtering(buf3_3,buf4_5,buf4_6,N/16);
  279.     filtering(buf3_4,buf4_7,buf4_8,N/16);
  280.     filtering(buf3_5,buf4_9,buf4_10,N/16);
  281.  
  282.     filtering(buf4_1,buf5_1,buf5_2,N/32);
  283.     filtering(buf4_2,buf5_3,buf5_4,N/32);
  284.     filtering(buf4_3,buf5_5,buf5_6,N/32);
  285.     filtering(buf4_4,buf5_7,buf5_8,N/32);
  286.     filtering(buf4_5,buf5_9,buf5_10,N/32);
  287.     filtering(buf4_6,buf5_11,buf5_12,N/32);
  288.     filtering(buf4_7,buf5_13,buf5_14,N/32);
  289.     filtering(buf4_8,buf5_15,buf5_16,N/32);
  290.     filtering(buf4_9,buf5_17,buf5_18,N/32);
  291.  
  292.   cswrite(buf5_1);
  293.   cswrite(buf5_2);
  294.   cswrite(buf5_3);
  295.   cswrite(buf5_4);
  296.   cswrite(buf5_5);
  297.   cswrite(buf5_6);
  298.   cswrite(buf5_7);
  299.   cswrite(buf5_8);
  300.   cswrite(buf5_9);
  301.   cswrite(buf5_10);
  302.   cswrite(buf5_11);
  303.   cswrite(buf5_12);
  304.   cswrite(buf5_13);
  305.   cswrite(buf5_14);
  306.   cswrite(buf5_15);
  307.   cswrite(buf5_16);
  308.   cswrite(buf5_17);
  309.   cswrite(buf5_18);
  310. }
  311.  
  312. void decode(unsigned long size)
  313. {
  314.   unsigned long i;
  315.  
  316.   unsigned long m = size / N;
  317.   unsigned long n = size % N;
  318.  
  319.   for(i = 0; i < m; ++i){
  320.     csread(buf5_1);
  321.     csread(buf5_2);
  322.     csread(buf5_3);
  323.     csread(buf5_4);
  324.     csread(buf5_5);
  325.     csread(buf5_6);
  326.     csread(buf5_7);
  327.     csread(buf5_8);
  328.     csread(buf5_9);
  329.     csread(buf5_10);
  330.     csread(buf5_11);
  331.     csread(buf5_12);
  332.     csread(buf5_13);
  333.     csread(buf5_14);
  334.     csread(buf5_15);
  335.     csread(buf5_16);
  336.     csread(buf5_17);
  337.     csread(buf5_18);
  338.  
  339.       untifilt(buf5_17,buf5_18,buf4_9,N/32);
  340.       untifilt(buf5_15,buf5_16,buf4_8,N/32);
  341.       untifilt(buf5_13,buf5_14,buf4_7,N/32);
  342.       untifilt(buf5_11,buf5_12,buf4_6,N/32);
  343.       untifilt(buf5_9,buf5_10,buf4_5,N/32);
  344.       untifilt(buf5_7,buf5_8,buf4_4,N/32);
  345.       untifilt(buf5_5,buf5_6,buf4_3,N/32);
  346.       untifilt(buf5_3,buf5_4,buf4_2,N/32);
  347.       untifilt(buf5_1,buf5_2,buf4_1,N/32);
  348.  
  349.       untifilt(buf4_9,buf4_10,buf3_5,N/16);
  350.       untifilt(buf4_7,buf4_8,buf3_4,N/16);
  351.       untifilt(buf4_5,buf4_6,buf3_3,N/16);
  352.       untifilt(buf4_3,buf4_4,buf3_2,N/16);
  353.       untifilt(buf4_1,buf4_2,buf3_1,N/16);
  354.  
  355.       untifilt(buf3_5,buf3_6,buf2_3,N/8);
  356.       untifilt(buf3_3,buf3_4,buf2_2,N/8);
  357.       untifilt(buf3_1,buf3_2,buf2_1,N/8);
  358.  
  359.       untifilt(buf2_3,buf2_4,buf1_2,N/4);
  360.       untifilt(buf2_1,buf2_2,buf1_1,N/4);
  361.  
  362.       untifilt(buf1_1,buf1_2,buffer,N/2);
  363.     fwrite((void *)&buffer[0],N*2,1,outfile);
  364.   }
  365.   csread(buf5_1);
  366.   csread(buf5_2);
  367.   csread(buf5_3);
  368.   csread(buf5_4);
  369.   csread(buf5_5);
  370.   csread(buf5_6);
  371.   csread(buf5_7);
  372.   csread(buf5_8);
  373.   csread(buf5_9);
  374.   csread(buf5_10);
  375.   csread(buf5_11);
  376.   csread(buf5_12);
  377.   csread(buf5_13);
  378.   csread(buf5_14);
  379.   csread(buf5_15);
  380.   csread(buf5_16);
  381.   csread(buf5_17);
  382.   csread(buf5_18);
  383.  
  384.     untifilt(buf5_17,buf5_18,buf4_9,N/32);
  385.     untifilt(buf5_15,buf5_16,buf4_8,N/32);
  386.     untifilt(buf5_13,buf5_14,buf4_7,N/32);
  387.     untifilt(buf5_11,buf5_12,buf4_6,N/32);
  388.     untifilt(buf5_9,buf5_10,buf4_5,N/32);
  389.     untifilt(buf5_7,buf5_8,buf4_4,N/32);
  390.     untifilt(buf5_5,buf5_6,buf4_3,N/32);
  391.     untifilt(buf5_3,buf5_4,buf4_2,N/32);
  392.     untifilt(buf5_1,buf5_2,buf4_1,N/32);
  393.  
  394.     untifilt(buf4_9,buf4_10,buf3_5,N/16);
  395.     untifilt(buf4_7,buf4_8,buf3_4,N/16);
  396.     untifilt(buf4_5,buf4_6,buf3_3,N/16);
  397.     untifilt(buf4_3,buf4_4,buf3_2,N/16);
  398.     untifilt(buf4_1,buf4_2,buf3_1,N/16);
  399.  
  400.     untifilt(buf3_5,buf3_6,buf2_3,N/8);
  401.     untifilt(buf3_3,buf3_4,buf2_2,N/8);
  402.     untifilt(buf3_1,buf3_2,buf2_1,N/8);
  403.  
  404.     untifilt(buf2_3,buf2_4,buf1_2,N/4);
  405.     untifilt(buf2_1,buf2_2,buf1_1,N/4);
  406.  
  407.     untifilt(buf1_1,buf1_2,buffer,N/2);
  408.   fwrite((void *)&buffer[0],n*2,1,outfile);
  409. }
  410.  
  411. int main(int argc, char *argv[])
  412. {
  413.     int i,j;
  414.     int ed_flag;
  415.     char *s,*input_filename,*output_filename;
  416.     unsigned long size;  /* 元のバイト数 */
  417.     char head[44];
  418.  
  419.     ed_flag = 0;
  420.  
  421.     if(argc != 4){
  422.         exit(-1);
  423.     }
  424.  
  425.     s = argv[1];
  426.     if(s[0] == '-'){
  427.         for(j = 1; s[j]; ++j){
  428.             switch(s[j]){
  429.                 /* 現れたもの勝ち */
  430.  
  431.                 case 'e':    ed_flag = 1;
  432.                             break;
  433.  
  434.                 case 'd':    ed_flag = -1;
  435.                             break;
  436.  
  437.                 default:    ;
  438.             }
  439.         }
  440.     }
  441.  
  442.     if ((infile  = fopen(argv[2], "rb")) == NULL){
  443.         exit(-1);
  444.     }
  445.     if ((outfile = fopen(argv[3], "wb")) == NULL){
  446.         exit(-1);
  447.     }
  448.  
  449.     if (ed_flag == 1) {
  450.         fread(head,44,1,infile);
  451.         fwrite(head,44,1,outfile);
  452.         fseek(infile, 0L, SEEK_END);  /* infile の末尾を探す */
  453.         size = ftell(infile);         /* infile のバイト数 */
  454.         fwrite(&size, sizeof size, 1, outfile);
  455.         fseek(infile,44,SEEK_SET);
  456.         encode((size-44)/2);       /* 圧縮 */
  457.     } else if(ed_flag == -1){
  458.         fread(head,44,1,infile);
  459.         fwrite(head,44,1,outfile);
  460.         fread(&size, sizeof size, 1, infile);  /* 元のバイト数 */
  461.         decode((size-44)/2);   /* 復元 */
  462.     }
  463.     fclose(infile);  fclose(outfile);
  464.     return EXIT_SUCCESS;
  465. }
  466.